import { Toast } from 'vant';

import { VALIDATE_SUCCESS_CODE, VALIDATE_EMPTY_CODE, ERROR_MSG_Map } from '@/constants/validate';

import { isServer, isIos, isWeixin, isPC } from './browser';
import { isCardID } from './card-id';
import { isComplexMoney } from './currency';
import { isStrictPsw } from './password';
import { isPhone, isTel } from './phone';
import { isEmail } from './email';
import { isQQ } from './qq';
import { isPostal } from './postal';
import { isIP } from './ip';
import { isUrl } from './url';
import { isFloat, isPlus, isPositiveNum, isNonnegativePositiveNumRegexp, isNumber } from './number';
import { isEnglish, isChinese } from './language';
import { isUpper, isLower } from './string';

// 带提示的格式校验 type 对应的处理函数
const VALIDATE_NAME_TO_FUNCTION = {
  cardId: isCardID,
  complexMoney: isComplexMoney,
  phone: isPhone,
  tel: isTel,
  email: isEmail,
  QQ: isQQ,
  postal: isPostal,
  ip: isIP,
  url: isUrl,
  //   float: isFloat,
  //   plus: isPlus,
  //   positiveNum: isPositiveNum,
  //   nonnegativePositiveNumRegexp: isNonnegativePositiveNumRegexp,
  //   number: isNumber,
  //   english: isEnglish,
  //   chinese: isChinese,
  //   upper: isUpper,
  //   lower: isLower,
};

/**
 * 提供常用的一些类型检测方式
 *
 *  - plus : 判断是否是正数  checkStr(-10 , 'plus') === false
 *  - float : 判断是否是非负浮点数  checkStr(1.02 , 'float') === true
 * @param {String} str 检测的值
 * @param {String} type 检测的类型
 *
 * @returns { Boolean }
 */
export const checkStr = (str, type) => {
  switch (type) {
    //   判断是否是服务器环境
    case 'isServer':
      return !!isServer();
    //   判断是否是IOS系统
    case 'isIos':
      return !!isIos();
    //   判断是否是微信公众号环境
    case 'isWeixin':
      return !!isWeixin();
    //   判断是否是PC浏览器环境
    case 'isPC':
      return !!isPC();
    //   身份证号码格式严格校验
    case 'isCardID':
      return !!isCardID(str);
    //   简单的身份证号码校验
    case 'card':
      return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(str);
    //  严格货币类型 可以为负值
    case 'isComplexMoney':
      return isComplexMoney(str);
    //   密码强度校验是否符合要求
    case 'isStrictPsw':
      return !!isStrictPsw(str);
    //  手机号码 格式校验
    case 'isPhone':
      return !!isPhone(str, false);
    //  座机 格式校验
    case 'isTel':
      return !!isTel(str, false);
    //  电子邮箱
    case 'isEmail':
      return !!isEmail(str, false);
    //QQ号
    case 'isQQ':
      return isQQ(str);
    //邮政编码
    case 'isPostal':
      return isPostal(str);
    // 网址
    case 'isUrl':
      return isUrl(str);
    // IP
    case 'isIP':
      return isIP(str);
    //  非负浮点数
    case 'isFloat':
      return isFloat(str);
    //  判断是否是正数
    case 'isPlus':
      return isPlus(str);
    //正整数
    case 'isPositiveNum':
      return isPositiveNum(str);
    //非负整数
    case 'isNonnegativePositiveNumRegexp':
      return isNonnegativePositiveNumRegexp(str);
    //数字
    case 'isNumber':
      return isNumber(str);
    //英文
    case 'isEnglish':
      return isEnglish(str);
    // 中文
    case 'isChinese':
      return isChinese(str);
    // 小写
    case 'isLower':
      return isLower(str);
    // 大写
    case 'isUpper':
      return isUpper(str);
    default:
      return true;
  }
};

/**
 *  提供内置的类型格式校验并自动处理异常格式信息
 *
 * @param { String } str 检测的值
 * @param { String } type 检测的类型
 * @param { Object } options 检测配置
 *
 * @returns boolean
 *
 */
export const validateAndTips = (
  str,
  type,
  {
    // 是否进行非空校验
    isValidateEmpty = true,
    // 对于校验格式成功是否提示，默认不提示
    isTipSuccess = false,
    // 是否对校验不成功的进行提示
    isTips = true,
    // 返回值是Boolean类型还是详细的错误ID
    returnBol = true,
  }
) => {
  // 如果没有配置此类型的错误提示，那么就不进行提示处理
  if (!ERROR_MSG_Map[type]) isTips = false;
  //   当前类型的错误提示 map 数据
  const typeErrorMsgMap = ERROR_MSG_Map[type];
  //   进行空值的校验
  if (isValidateEmpty && !str) {
    if (isTips && typeErrorMsgMap[0]) Toast.fail(`${typeErrorMsgMap[0]}`);
    return returnBol ? false : VALIDATE_EMPTY_CODE;
  }
  let result;
  //   获取对应的格式判断函数
  if (VALIDATE_NAME_TO_FUNCTION[type]) {
    result = VALIDATE_NAME_TO_FUNCTION[type](str, true);
    if (result != VALIDATE_SUCCESS_CODE) {
      Toast.fail(`${typeErrorMsgMap[result]}`);
      return returnBol ? false : result;
    }
  }
  //   格式校验正确提示
  if (isTipSuccess) {
    Toast.success(`${typeErrorMsgMap[0]}`);
  }
  return returnBol ? result == VALIDATE_SUCCESS_CODE : result;
};
